/*
 * Created on 2005-3-10
 */
package com.hd123.rumba.util;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.exception.ParameterException;

/**
 * @author caili
 */
public class ObjectUtil {

  /**
   * 将一个对象的各个字段组成一个HashMap的项
   * 
   * @param object
   * @return
   */
  public static HashMap getFields(Object object) {
    return getFields(object, false);
  }

  /**
   * 将一个对象的各个字段组成一个HashMap的项
   * 
   * @param object
   * @return
   */
  public static HashMap getFields(Object object, boolean filedNameUppercase) {
    Field[] fields = object.getClass().getDeclaredFields();
    HashMap h = new HashMap(fields.length);
    AccessibleObject.setAccessible(fields, true);
    for (int i = 0; i < fields.length; ++i) {
      try {
        // Object value = fields[i].get(object);
        h.put(filedNameUppercase ? fields[i].getName().toUpperCase() : fields[i].getName(),
            fields[i].get(object));
      } catch (IllegalArgumentException e) {
        h.put(fields[i].getName(), e.toString());
      } catch (IllegalAccessException e) {
        h.put(fields[i].getName(), e.toString());
      }
    }
    return h;
  }

  /**
   * 如果o1是空, 返回o2; 否则返回o1
   * 
   * @param o1
   * @param o2
   * @return
   */
  public static Object nvl(Object o1, Object o2) {
    return o1 == null ? o2 : o1;
  }

  public static Object getFieldValue(Object object, String fieldName)
      throws InvocationTargetException, SecurityException, IllegalArgumentException,
      NoSuchMethodException, IllegalAccessException {
    char[] ca = fieldName.toCharArray();
    ca[0] = Character.toUpperCase(ca[0]);
    String methodName = "get" + new String(ca);
    Method method = object.getClass().getMethod(methodName, (Class[]) null);
    return method.invoke(object, (Object[]) null);
  }

  public static boolean equals(Object o1, Object o2) {
    if (o1 == null && o2 == null)
      return true;
    else if (o1 == null && o2 != null)
      return false;
    else if (o1 != null && o2 == null)
      return false;
    else if (o1 instanceof Timestamp) {
      if (o2 instanceof Timestamp)
        return o1.equals(o2);
      else if (o2 instanceof Date)
        return ((Date) o1).getTime() == ((Date) o2).getTime();
      else
        return false;
    } else if (o2 instanceof Timestamp) {
      if (o1 instanceof Timestamp)
        return o1.equals(o2);
      else if (o1 instanceof Date)
        return ((Date) o1).getTime() == ((Date) o2).getTime();
      else
        return false;
    } else
      return o1.equals(o2);
  }

  public static final int dbtypeUnset = 0;
  public static final int dbtypeMySql = 1;
  public static final int dbtypeOracle = 2;
  public static final int dbtypeMsSql = 3;

  public static int getDbType(Connection connection) {
    try {
      String url = connection.getMetaData().getURL().toLowerCase();
      if (url.contains("jdbc:mysql:"))
        return dbtypeMySql;
      else if (url.contains("jdbc:microsoft:sqlserver:"))
        return dbtypeMsSql;
      else if (url.contains("jdbc:sqljdbc:"))
        return dbtypeMsSql;
      else if (url.contains("jdbc:oracle:"))
        return dbtypeOracle;
    } catch (SQLException e) {
    }
    return dbtypeUnset;
  }

  public static String getErrorTrace(Throwable t) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    PrintStream s = new PrintStream(bos);
    t.printStackTrace(s);
    return bos.toString();
  }

  public static void checkParameterNotNull(Object param, String paramName)
      throws ParameterException {
    if (param == null)
      throw new ParameterException("必须的参数" + paramName + "不能为null");
  }

  /**
   * 取得指定类定义的功能权限的标识列表。
   * 
   * @param definitionClass
   *            定义类
   * @return 标识列表
   * @throws BusinessException
   */
  public static Collection<String> extractPermissionIds(Class definitionClass)
      throws BusinessException {
    Collection<String> permIds = new ArrayList<String>();
    Field[] fields = definitionClass.getDeclaredFields();
    for (Field field : fields) {
      if (field.getName().startsWith("PERMISSION_")) {
        try {
          String permCode = (String) field.get(null);
          permIds.add(permCode);
        } catch (Exception e) {
          throw new BusinessException(e);
        }
      }
    }
    return permIds;
  }


  /**
   * 提供业务级别的断言功能。
   * <p>
   * 不同于Java环境所提供的assert，如果断言不成立，则将以异常的方式抛出错误，且不会受到javac编译参数“-ea”的影响。
   * 
   * @param judge
   * @param echo
   * @throws BusinessException
   */
  public static void assertion(boolean judge, String echo) throws BusinessException {
    if (!judge)
      throw new BusinessException(echo);
  }

  /**
   * 提供业务级别的断言功能。
   * <p>
   * 不同于Java环境所提供的assert，如果断言不成立，则将以异常的方式抛出错误，且不会受到javac编译参数“-ea”的影响。
   * 
   * @param judge
   * @param pattern
   * @param arguments
   * @throws BusinessException
   */
  public static void assertion(boolean judge, String pattern, Object... arguments)
      throws BusinessException {
    if (!judge)
      throw new BusinessException(pattern, arguments);
  }

  /**
   * 提供业务级别的断言功能。
   * <p>
   * 不同于Java环境所提供的assert，如果断言不成立，则将以异常的方式抛出错误，且不会受到javac编译参数“-ea”的影响。
   * 
   * @param e
   * @throws BusinessException
   */
  public static void assertion(boolean judge, BusinessException e) throws BusinessException {
    if (!judge)
      throw e;
  }
}
